package com.baoteng.scan.creater;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.text.TextUtils;
import android.widget.ImageView;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;

import java.util.Hashtable;

/**
 * Author: loren
 * Date: 2019/9/18
 */
public class QrCodeCreater {

    private static final int DEFAULT_WIDTH = 300;
    private static final int DEFAULT_COLOR = 0x00000000;
    private static final Bitmap.Config DEFAULT_CONFIG = Bitmap.Config.RGB_565;

    public Bitmap create(QrCodeParams params) {
        if (params == null) {
            return null;
        }
        String content = params.getContent();
        if (TextUtils.isEmpty(content)) {
            return null;
        }
        int width = params.getWidth();
        int height = params.getHeight();
        if (width == 0) {
            width = DEFAULT_WIDTH;
        }
        if (height == 0) {
            height = DEFAULT_WIDTH;
        }
        int color = params.getColor();
        if (color == 0) {
            color = DEFAULT_COLOR;
        }
        Bitmap.Config config = params.getConfig();
        if (config == null) {
            config = DEFAULT_CONFIG;
        }

        QRCodeWriter qrCodeWriter = new QRCodeWriter();
        Hashtable<EncodeHintType, String> hints = new Hashtable<>();
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        hints.put(EncodeHintType.MARGIN, "0");
        try {
            BitMatrix matrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, width, height, hints);
//            matrix = deleteWhite(matrix);//删除白边
            width = matrix.getWidth();
            height = matrix.getHeight();
            int[] pixels = new int[width * height];
            for (int i = 0; i < height; i++) {
                for (int j = 0; j < width; j++) {
                    if (matrix.get(j, i)) {
                        pixels[i * width + j] = color;
                    } else {
                        pixels[i * width + j] = 0xffffffff;
                    }
                }
            }
            Bitmap bitmap = Bitmap.createBitmap(pixels, 0, width, width, height, config);
            if (params.getCenterLogo() == null) {
                return bitmap;
            } else {
                return addLogo(bitmap, params.getCenterLogo());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Bitmap addLogo(Bitmap qrBitmap, Bitmap logoBitmap) {
        int qrBitmapWidth = qrBitmap.getWidth();
        int qrBitmapHeight = qrBitmap.getHeight();
        int logoBitmapWidth = logoBitmap.getWidth();
        int logoBitmapHeight = logoBitmap.getHeight();
        Bitmap blankBitmap = Bitmap.createBitmap(qrBitmapWidth, qrBitmapHeight, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(blankBitmap);
        canvas.drawBitmap(qrBitmap, 0, 0, null);
        canvas.save();
        float scaleSize = 1.0f;
        while ((logoBitmapWidth / scaleSize) > (qrBitmapWidth / 5) || (logoBitmapHeight / scaleSize) > (qrBitmapHeight / 5)) {
            scaleSize *= 2;
        }
        float sx = 1.0f / scaleSize;
        canvas.scale(sx, sx, qrBitmapWidth / 2, qrBitmapHeight / 2);
        canvas.drawBitmap(logoBitmap, (qrBitmapWidth - logoBitmapWidth) / 2, (qrBitmapHeight - logoBitmapHeight) / 2, null);
        canvas.restore();
        return blankBitmap;
    }

    public static class Builder {
        private QrCodeParams params;

        public Builder() {
            this.params = new QrCodeParams();
        }

        public Builder content(String content) {
            params.setContent(content);
            return this;
        }

        public Builder size(int width, int height) {
            params.setWidth(width);
            params.setHeight(height);
            return this;
        }

        public Builder color(int color) {
            params.setColor(color);
            return this;
        }

        public Builder centerLogo(Bitmap logo) {
            params.setCenterLogo(logo);
            return this;
        }

        public Builder config(Bitmap.Config config) {
            params.setConfig(config);
            return this;
        }

        public Bitmap create() {
            return new QrCodeCreater().create(params);
        }

        public void into(ImageView view) {
            if (view == null) {
                return;
            }
            view.setImageBitmap(new QrCodeCreater().create(params));
        }
    }
}
